﻿using SharpSoft.Geometries.Shapes;
using System;
using System.Collections.Generic;
using System.Text;

namespace SharpSoft.Geometries
{
    /// <summary>
    /// 描述二维空间中直角坐标系的一个点
    /// </summary>
    public struct Point2D
    {
        internal double _x;

        internal double _y;

        public double X
        {
            get
            {
                return _x;
            }
            set
            {
                _x = value;
            }
        }

        public double Y
        {
            get
            {
                return _y;
            }
            set
            {
                _y = value;
            }
        }

        public static bool operator ==(Point2D point1, Point2D point2)
        {
            if (point1.X == point2.X)
            {
                return point1.Y == point2.Y;
            }
            return false;
        }

        public static bool operator !=(Point2D point1, Point2D point2)
        {
            return !(point1 == point2);
        }

        public static bool Equals(Point2D point1, Point2D point2)
        {
            double num = point1.X;
            if (num.Equals(point2.X))
            {
                num = point1.Y;
                return num.Equals(point2.Y);
            }
            return false;
        }

        public override bool Equals(object o)
        {
            if (o != null && o is Point2D)
            {
                Point2D point = (Point2D)o;
                return Equals(this, point);
            }
            return false;
        }

        public bool Equals(Point2D value)
        {
            return Equals(this, value);
        }

        public override int GetHashCode()
        {
            double num = X;
            int hashCode = num.GetHashCode();
            num = Y;
            return hashCode ^ num.GetHashCode();
        }


        public Point2D(double x, double y)
        {
            _x = x;
            _y = y;
        }

        public void Offset(double offsetX, double offsetY)
        {
            _x += offsetX;
            _y += offsetY;
        }

        public static Point2D operator +(Point2D point, Vector2D vector)
        {
            return new Point2D(point._x + vector._x, point._y + vector._y);
        }

        public static Point2D Add(Point2D point, Vector2D vector)
        {
            return new Point2D(point._x + vector._x, point._y + vector._y);
        }

        public static Point2D operator -(Point2D point, Vector2D vector)
        {
            return new Point2D(point._x - vector._x, point._y - vector._y);
        }

        public static Point2D Subtract(Point2D point, Vector2D vector)
        {
            return new Point2D(point._x - vector._x, point._y - vector._y);
        }

        public static Vector2D operator -(Point2D point1, Point2D point2)
        {
            return new Vector2D(point1._x - point2._x, point1._y - point2._y);
        }

        public static Vector2D Subtract(Point2D point1, Point2D point2)
        {
            return new Vector2D(point1._x - point2._x, point1._y - point2._y);
        }

        public static Point2D operator *(Point2D point, Transform2D matrix)
        {
            return matrix.Transform(point);
        }

        public static Point2D Multiply(Point2D point, Transform2D matrix)
        {
            return matrix.Transform(point);
        }

        public static explicit operator Size2D(Point2D point)
        {
            return new Size2D(Math.Abs(point._x), Math.Abs(point._y));
        }

        public static explicit operator Vector2D(Point2D point)
        {
            return new Vector2D(point._x, point._y);
        }

        public override string ToString()
        {
            return $"[{X},{Y}]";
        }
        /// <summary>
        /// 平移当前点得到新的点
        /// </summary>
        /// <param name="offsetx"></param>
        /// <param name="offsety"></param>
        /// <returns></returns>
        public Point2D Translate(double offsetx, double offsety)
        {
            return new Point2D(this.X + offsetx, this.Y + offsety);
        }
        /// <summary>
        /// 是否是无效的点
        /// </summary>
        /// <returns></returns>
        public bool IsNaP()
        {
            return double.IsNaN(this.X) || double.IsNaN(this.Y);
        }
    }
}
